package com.amt.olcacon.utils;

import java.time.Instant;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class Snowflake16Bit {
    // 起始时间戳（2023-01-01 00:00:00）
    private static final long EPOCH = 1672531200L;

    // 机器 ID（10 bit，可自定义）
    private final long machineId;

    // 上一次生成 ID 的时间戳
    private long lastTimestamp = -1L;

    // 序列号（8 bit）
    private long sequence = 0L;

    public Snowflake16Bit(long machineId) {
        if (machineId < 0 || machineId > 1023) {
            throw new IllegalArgumentException("Machine ID must be between 0 and 1023");
        }
        this.machineId = machineId;
    }

    public synchronized long nextId() {
        long currentTimestamp = getCurrentTimestamp();

        if (currentTimestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards!");
        }

        if (currentTimestamp == lastTimestamp) {
            // 同一秒内，序列号自增
            sequence = (sequence + 1) & 0xFF; // 8 bit 最大值 255
            if (sequence == 0) {
                // 如果序列号用尽，等待到下一秒
                currentTimestamp = waitNextSecond(currentTimestamp);
            }
        } else {
            // 不同秒，序列号重置
            sequence = 0L;
        }

        lastTimestamp = currentTimestamp;

        // 组合成 56 bit ID
        long id = ((currentTimestamp - EPOCH) << 18) // 38 bit 时间戳
                | (machineId << 8)                  // 10 bit 机器 ID
                | sequence;                         // 8 bit 序列号

        // 转换为 16 位数字（可能小于 16 位时前面补 0）
        return id % 10_000_000_000_000_000L; // 确保 16 位
    }

    private long getCurrentTimestamp() {
        return Instant.now().getEpochSecond(); // 秒级时间戳
    }

    private long waitNextSecond(long currentTimestamp) {
        long now;
        do {
            now = getCurrentTimestamp();
        } while (now <= currentTimestamp);
        return now;
    }




    public static void main(String[] args) {
        Snowflake16Bit snowflake = new Snowflake16Bit(1); // 机器 ID = 1
        for (int i = 0; i < 10; i++) {
            long id = snowflake.nextId();
            System.out.println("Generated ID: " + String.format("%016d", id));
        }
    }
}